// src/main/java/com/example/coursehub/service/impl/CourseClassServiceImpl.java
package com.example.coursehub.service.impl;

import com.example.coursehub.entity.*;

import com.example.coursehub.repository.*;
import com.example.coursehub.service.ClassService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class ClassServiceImpl implements ClassService {

    private ClassesRepository classRepository = null;
    private CourseRepository courseRepository = null;
    private UserRepository userRepository = null;
    private ClassesStudentRepository classesStudentRepository = null;
    private ClassesTeacherRepository classesTeacherRepository = null;
    private CourseTeacherRepository courseTeacherRepository = null;
    @Autowired
    public void ClassServiceImpl(ClassesRepository classRepository,
                                 CourseRepository courseRepository,
                                 UserRepository userRepository,
                                 ClassesStudentRepository classesStudentRepository,
                                 ClassesTeacherRepository classesTeacherRepository,
                                 CourseTeacherRepository courseTeacherRepository ) {
        this.classRepository = classRepository;
        this.courseRepository = courseRepository;
        this.userRepository = userRepository;
        this.classesStudentRepository = classesStudentRepository;
        this.classesTeacherRepository = classesTeacherRepository;
        this.courseTeacherRepository = courseTeacherRepository;
    }


    @Override
    @Transactional
    public Classes createClass(Classes classEntity) {
        // 1. 检查 course 对象是否为 null
        if (classEntity.getCourse() == null) {
            throw new IllegalArgumentException("Class must have a course associated. Course object cannot be null.");
        }
        // 2. 检查 course ID 是否为 null
        String courseId = classEntity.getCourse().getCourseId();
        if (courseId == null) {
            throw new IllegalArgumentException("Course ID cannot be null when creating a class.");
        }

        // 现在 courseRepository 将被正确注入
        Course course = courseRepository.findById(courseId)
                .orElseThrow(() -> new NoSuchElementException("Course not found with ID: " + courseId));
        classEntity.setCourse(course);
        // 现在 classRepository 将被正确注入
        return classRepository.save(classEntity);
    }

    @Override
    @Transactional
    public Classes updateClass(String classId, Classes classDetails) {
        // 现在 classRepository 将被正确注入
        Classes existingClass = classRepository.findById(classId)
                .orElseThrow(() -> new NoSuchElementException("Class not found with ID: " + classId));

        existingClass.setClassesName(classDetails.getClassesName());
        // 增加对 classDetails.getCourse() 的 null 检查
        if (classDetails.getCourse() != null && classDetails.getCourse().getCourseId() != null) {
            String courseId = classDetails.getCourse().getCourseId();
            // 现在 courseRepository 将被正确注入
            Course course = courseRepository.findById(courseId)
                    .orElseThrow(() -> new NoSuchElementException("Course not found with ID: " + courseId));
            existingClass.setCourse(course);
        } else if (classDetails.getCourse() != null && classDetails.getCourse().getCourseId() == null) {
            throw new IllegalArgumentException("Provided Course object has a null Course ID.");
        }
        return classRepository.save(existingClass);
    }

    @Override
    @Transactional
    public void deleteClass(String classId) {
        classRepository.deleteById(classId);
    }

    @Override
    @Transactional(readOnly = true)
    public Classes getClassById(String classId) {
        return classRepository.findById(classId)
                .orElseThrow(() -> new NoSuchElementException("Class not found with ID: " + classId));
    }

    @Override
    @Transactional(readOnly = true)
    public List<Classes> getAllClasses() {
        return classRepository.findAll();
    }

    @Override
    @Transactional
    public void addStudentToClass(String classesId, String userId) {
        Classes classes = classRepository.findById(classesId)
                .orElseThrow(() -> new NoSuchElementException("Class not found with ID: " + classesId));
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new NoSuchElementException("User not found with ID: " + userId));

        if (classesStudentRepository.findByClasses_ClassesIdAndUser_UserId(classesId, userId).isPresent()) {
            throw new RuntimeException("Student " + user.getUserName() + " is already in class " + classes.getClassesName());
        }

        ClassesStudentId studentId = new ClassesStudentId();
        ClassesStudent classesStudent = new ClassesStudent();
        classesStudent.setId(studentId);
        classesStudent.setClasses(classes);
        classesStudent.setUser(user);

        classesStudentRepository.save(classesStudent);
    }

    @Override
    @Transactional
    public void removeStudentFromClass(String classesId, String userId) {
        classesStudentRepository.deleteByClasses_ClassesIdAndUser_UserId(classesId, userId);
    }

    @Override
    @Transactional
    public void addTeacherToClass(String classesId, String userId) {
        Classes classes = classRepository.findById(classesId)
                .orElseThrow(() -> new NoSuchElementException("Class not found with ID: " + classesId));
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new NoSuchElementException("User not found with ID: " + userId));

        if (classesTeacherRepository.findByClasses_ClassesIdAndUser_UserId(classesId, userId).isPresent()) {
            throw new RuntimeException("Teacher " + user.getUserName() + " is already assigned to class " + classes.getClassesName());
        }

        ClassesTeacherId teacherId = new ClassesTeacherId();
        ClassesTeacher classesTeacher = new ClassesTeacher();
        classesTeacher.setId(teacherId);
        classesTeacher.setClasses(classes);
        classesTeacher.setUser(user);

        classesTeacherRepository.save(classesTeacher);
    }

    @Override
    @Transactional
    public void removeTeacherFromClass(String classesId, String userId) {
        classesTeacherRepository.deleteByClasses_ClassesIdAndUser_UserId(classesId, userId);
    }

    @Override
    @Transactional(readOnly = true)
    public List<User> getTeachersInClass(String classesId) {
        try {
            Optional<Classes> optionalClass = classRepository.findById(classesId);

            if (optionalClass.isEmpty()) {
                return Collections.emptyList(); // 未找到班级，返回空列表
            }

            Classes classes = optionalClass.get();

            List<ClassesTeacher> classesTeachers = classesTeacherRepository.findByClasses(classes);

            List<User> teachers = classesTeachers.stream()
                    .map(ClassesTeacher::getUser)
                    .collect(Collectors.toList());

            teachers.forEach(teacher -> System.out.println("DEBUG: 找到教师: " + teacher.getUserName() + " (ID: " + teacher.getUserId() + ")")); // 日志 5

            return teachers;
        } catch (Exception e) {
            e.printStackTrace(); // 打印详细错误堆栈
            return Collections.emptyList(); // 出现任何意外错误时返回空列表
        }
    }

    @Override
    @Transactional(readOnly = true)
    public List<User> getStudentsInClass(String classesId) {
        Classes classes = classRepository.findById(classesId)
                .orElseThrow(() -> new NoSuchElementException("Class not found with ID: " + classesId));
        return classesStudentRepository.findByClasses(classes).stream()
                .map(ClassesStudent::getUser)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(readOnly = true)
    public Classes getClassByStudentId(String studentId) {
        User student = userRepository.findById(studentId)
                .orElseThrow(() -> new NoSuchElementException("Student not found with ID: " + studentId));
        return classesStudentRepository.findByUser(student).stream()
                .map(ClassesStudent::getClasses)
                .findFirst()
                .orElse(null);
    }

    @Override
    @Transactional
    public void addExerciseToClass(String classesId, String exerciseId) {
        System.out.println("Placeholder: Adding exercise " + exerciseId + " to class " + classesId);
    }

    @Override
    @Transactional
    public void removeTeachingAssistantFromClass(String classesId, String userId) {
        removeTeacherFromClass(classesId, userId);
    }

    @Override
    @Transactional
    public void addTeachingAssistantToClass(String classesId, String userId) {
        addTeacherToClass(classesId, userId);
    }

    @Override
    @Transactional
    public void removeExerciseFromClass(String classesId, String exerciseId) {
        System.out.println("Placeholder: Removing exercise " + exerciseId + " from class " + classesId);
    }

    @Override
    @Transactional(readOnly = true)
    public Classes getClassByTeacherId(String teacherId) {
        User teacher = userRepository.findById(teacherId)
                .orElseThrow(() -> new NoSuchElementException("Teacher not found with ID: " + teacherId));
        return classesTeacherRepository.findByUser(teacher).stream()
                .map(ClassesTeacher::getClasses)
                .findFirst()
                .orElse(null);
    }
    @Override
    public List<Classes> getClassesByCourseId(String courseId) {
        return classRepository.findByCourseCourseId(courseId);
    }
    @Override
    public boolean hasUserJoinedAnyClass(String courseId, String userId) {
        List<Classes> classes = classRepository.findByCourseCourseId(courseId);
        for (Classes cls : classes) {
            Optional<ClassesStudent> sc = classesStudentRepository.findByClasses_ClassesIdAndUser_UserId(
                    cls.getClassesId(), userId
            );
            if (sc.isPresent()) return true;
        }
        return false;
    }
    @Override
    public Map<String, List<String>> getClassMembers(String userId, String courseId) {
        List<Classes> classList = classRepository.findByCourseCourseId(courseId);

        if (classList.isEmpty()) {
            throw new RuntimeException("该课程下没有班级");
        }

        // 获取用户加入的班级
        Optional<ClassesStudent> cs = classesStudentRepository.findByUser_UserId(userId);
        if (cs.isEmpty()) {
            throw new RuntimeException("该用户尚未加入任何班级");
        }

        String classId = cs.get().getClasses().getClassesId();

        // 判断该班级是否属于该课程下
        boolean classInCourse = classList.stream()
                .anyMatch(c -> c.getClassesId().equals(classId));

        if (!classInCourse) {
            throw new RuntimeException("该用户不在该课程下的班级中");
        }
        // 获取教师列表
        List<String> teachers = classesTeacherRepository.findByClasses_ClassesId(classId)
                .stream()
                .map(ct -> ct.getUser().getUserName())
                .collect(Collectors.toList());

        // 获取该班级内所有学生
        List<String> students = classesStudentRepository.findByClasses_ClassesId(classId)
                .stream()
                .map(csItem -> csItem.getUser().getUserName())
                .collect(Collectors.toList());

        Map<String, List<String>> result = new HashMap<>();
        result.put("teachers", teachers);
        result.put("students", students);
        return result;
    }
    @Override
    @Transactional(readOnly = true)
    public List<Classes> getClassesByTeacherAndCourse(String teacherId, String courseId) {
        User teacher = userRepository.findById(teacherId)
                .orElseThrow(() -> new NoSuchElementException("Teacher not found with ID: " + teacherId));
        List<ClassesTeacher> teacherAssociations = classesTeacherRepository.findByUser(teacher);

        return teacherAssociations.stream()
                .map(ClassesTeacher::getClasses)
                .filter(cls -> cls.getCourse() != null && cls.getCourse().getCourseId().equals(courseId))
                .collect(Collectors.toList());
    }
    
}
